package com.my.myTradeData;

import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.hibernate.Session;
import org.zeromq.ZMQ;

import com.my.myTradeData.DataSource.Dictionary;
import com.my.stock.core.TradeService;
import com.my.stock.core.Turtle;

/**
 * Hello world!
 *
 */
public class App extends Application<MyConfiguration>{

	@Override
	public void run(MyConfiguration configuration, Environment environment) throws Exception {		
		final MyResource resource = new MyResource(
	        configuration.getTemplate(),
	        configuration.getDefaultName()
	    );
		environment.jersey().register(resource);
		
		final MyHealthCheck healthCheck = new MyHealthCheck(configuration.getTemplate());
		environment.healthChecks().register("template", healthCheck);
	}
	
	@Override
	public String getName() {
		return "hello-world";
	}

	@Override
	public void initialize(Bootstrap<MyConfiguration> bootstrap) {
		super.initialize(bootstrap);
	}

	
	
	private static int insertCount = 0;

	public static Queue<Trade> tradeQueue = new ArrayBlockingQueue<Trade>(1024 * 1000);

	public static Queue<String> realDataQueue = new ArrayBlockingQueue<String>(1024 * 1000);

	private static void initMarketOpen() {
		//Turtle.init();
	}

	public static void main(String[] args) throws NumberFormatException, Exception {

		Thread getRealDataThread = new Thread(new Runnable() {
			public void run() {
				ZMQ.Context context = ZMQ.context(1);
				ZMQ.Socket s = context.socket(ZMQ.REP);
				s.bind("tcp://*:5672");
				while (true) {
					byte[] request = s.recv(); // 获取request发送过来的数据
					realDataQueue.offer(new String(request));
					String response = "";
					s.send(response.getBytes());
				}
			}
		});
		getRealDataThread.start();

		Thread tradeThread = new Thread(new Runnable() {
			public void run() {

				ZMQ.Context context = ZMQ.context(1);
				ZMQ.Socket s = context.socket(ZMQ.REQ);
				s.connect("tcp://*:5671");
				while (true) {
					Trade trade = tradeQueue.poll();
					if (trade != null) {
						String message = "";
						if (trade.getDirect() == TradeService.SIGNAL_BUY) {
							message = "buy,";
						} else if (trade.getDirect() == TradeService.SIGNAL_SELL) {
							message = "sell,";
						} else if (trade.getDirect() == TradeService.SIGNAL_LONGSTOP) {
							message = "longstop,";
						} else if (trade.getDirect() == TradeService.SIGNAL_LONGSTOP) {
							message = "shortstop,";
						}
						message = message + trade.getCode() + "," + trade.getNumber() + "," + trade.getBuylimit() + "," + trade.getSelllimit()+'\0';
						s.send(message.getBytes(), 0);
						s.recv(0);
					}

				}

			}

		});
		tradeThread.start();

		Thread signalThread = new Thread(new Runnable() {
			public void run() {
				while (true) {

					String req = realDataQueue.poll();
					if (req != null) {
						String[] reqSplit = req.split(",");
						Turtle t = Turtle.getInstance(reqSplit[0]);
						if (t != null) {
							t.signal(Double.parseDouble(reqSplit[1]), Double.parseDouble(reqSplit[2]), Double.parseDouble(reqSplit[3]), Double.parseDouble(reqSplit[4]));
						}
					}
				}

			}
		});
		signalThread.start();
		initMarketOpen();
		// while (true) {
		// Date date = new Date();
		// boolean execute = false;
		// if (date.getHours() == 8 && date.getMinutes() == 45 &&
		// date.getSeconds() == 0) {
		// try {
		// initMarketOpen();
		// Thread.sleep(1000 * 60);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		//
		// if (date.getHours() == 20 && date.getMinutes() == 45 &&
		// date.getSeconds() == 0) {
		// try {
		// initMarketOpen();
		// Thread.sleep(1000 * 60);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		//
		// }

		//
		// String code[] = { "TA0", "OI0", "RS0", "RM0", "ZC0", "WH0", "JR0",
		// "SR0", "CF0", "RI0", "MA0", "FG0", "LR0", "SF0", "SM0", "V0", "P0",
		// "B0", "M0", "I0", "JD0", "L0",
		// "PP0", "FB0", "BB0", "Y0", "C0", "A0", "J0", "JM0", "CS0", "FU0",
		// "AL0", "RU0", "ZN0", "CU0", "AU0", "RB0", "WR0", "PB0", "AG0", "BU0",
		// "HC0", "SN0", "NI0" };
		// Map<String, String> m = new HashMap<String, String>();
		//
		// m.put("TA0", "PTA连续");
		// m.put("OI0", "菜油连续");
		// m.put("RS0", "菜籽连续");
		// m.put("RM0", "菜粕连续");
		// m.put("ZC0", "动力煤连续");
		// m.put("WH0", "强麦连续");
		// m.put("JR0", "粳稻连续");
		// m.put("SR0", "白糖连续");
		// m.put("CF0", "棉花连续");
		// m.put("RI0", "早籼稻连续");
		// m.put("MA0", "郑醇连续");
		// m.put("FG0", "玻璃连续");
		// m.put("LR0", "晚籼稻连续");
		// m.put("SF0", "硅铁连续");
		// m.put("SM0", "锰硅连续");
		// m.put("V0", "PVC连续");
		// m.put("P0", "棕榈连续");
		// m.put("B0", "豆二连续");
		// m.put("M0", "豆粕连续");
		// m.put("I0", "铁矿石连续");
		// m.put("JD0", "鸡蛋连续");
		// m.put("L0", "塑料连续");
		// m.put("PP0", "PP连续");
		// m.put("FB0", "纤维板连续");
		// m.put("BB0", "胶合板连续");
		// m.put("Y0", "豆油连续");
		// m.put("C0", "玉米连续");
		// m.put("A0", "豆一连续");
		// m.put("J0", "焦炭连续");
		// m.put("JM0", "焦煤连续");
		// m.put("CS0", "玉米淀粉连续");
		// m.put("FU0", "燃油连续");
		// m.put("AL0", "沪铝连续");
		// m.put("RU0", "橡胶连续");
		// m.put("ZN0", "沪锌连续");
		// m.put("CU0", "沪铜连续");
		// m.put("AU0", "黄金连续");
		// m.put("RB0", "螺纹钢连续");
		// m.put("WR0", "线材连续");
		// m.put("PB0", "沪铅连续");
		// m.put("AG0", "白银连续");
		// m.put("BU0", "沥青连续");
		// m.put("HC0", "热轧卷板连续");
		// m.put("SN0", "沪锡连续");
		// m.put("NI0", "沪镍连续");
		// for (String c : code) {
		// // 创建HttpClient实例
		// HttpClient httpclient = new DefaultHttpClient();
		// // 创建Get方法实例
		// HttpGet httpgets = new
		// HttpGet("http://stock2.finance.sina.com.cn/futures/api/json.php/IndexService.getInnerFuturesDailyKLine?symbol="
		// + c);
		// HttpResponse response = httpclient.execute(httpgets);
		// HttpEntity entity = response.getEntity();
		// if (entity != null) {
		// InputStream instreams = entity.getContent();
		// String str = convertStreamToString(instreams);
		// str = str.substring(2, str.length() - 3);
		// String[] datas = str.split("],\\[");
		// readDatas(c, datas);
		// // System.out.println(c + " atr:" + getATR(c, 26));
		//
		// httpgets.abort();
		// }
		// }
		//
		// for (String c : code) {
		// // 创建HttpClient实例
		// HttpClient httpclient = new DefaultHttpClient();
		// // 创建Get方法实例
		// HttpGet httpgets = new HttpGet("http://hq.sinajs.cn/list=" + c);
		// HttpResponse response = httpclient.execute(httpgets);
		// HttpEntity entity = response.getEntity();
		// if (entity != null) {
		// InputStream instreams = entity.getContent();
		// String str = convertStreamToString(instreams);
		// str = str.substring(2, str.length() - 3);
		// DayData dd = readRealtimeDatas(c, str);
		// double maxmin[] = getOrderDayData(c, 55);
		// if (dd.getClose() > maxmin[0] || dd.getClose() < maxmin[1]) {
		// System.out.println("m.put(\"" + c + "\",\"" +
		// dd.getName().replaceAll("r hq_str_", "").replaceAll(c,
		// "").replaceAll("=", "") + "\");");
		// } else {
		// // System.out.println("m.put(\"" + c + "\"," +
		// // dd.getName().replaceAll("r hq_str_",
		// // "").replaceAll(c, "").replaceAll("=", "") + "\");");
		// }
		// httpgets.abort();
		// }
		//
		// System.out.println("-----------------------");
		// }
	}

	public static void main1(String[] args) throws Exception {
		
		new App().run("server", "d:/hello-world.yml");
		// String code[] = { "TA0", "OI0", "RS0", "RM0", "ZC0", "WH0", "JR0",
		// "SR0", "CF0", "RI0", "MA0", "FG0", "LR0", "SF0", "SM0", "V0", "P0",
		// "B0", "M0", "I0", "JD0", "L0",
		// "PP0", "FB0", "BB0", "Y0", "C0", "A0", "J0", "JM0", "CS0", "FU0",
		// "AL0", "RU0", "ZN0", "CU0", "AU0", "RB0", "WR0", "PB0", "AG0", "BU0",
		// "HC0", "SN0", "NI0" };
		//
		// for (String c : code) {
		// try {
		// writeTodayData(c);
		// } catch (NumberFormatException e) {
		// e.printStackTrace();
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		// }
		// while (true) {
		// Date date = new Date();
		// boolean execute = false;
		// if (date.getHours() == 8 && date.getMinutes() == 45 &&
		// date.getSeconds() == 0) {
		// System.out.println(date.getHours() + ":" + date.getMinutes() + ":" +
		// date.getSeconds());
		// try {
		// Thread.sleep(1000 * 60);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		//
		// }

		// Trade trade = tradeQueue.poll();
		// ZMQ.Context context = ZMQ.context(1);
		// ZMQ.Socket s = context.socket(ZMQ.REQ);
		// s.connect("tcp://*:5671");
		// String message = "buy,v1701,1,30000,40000";
		// // if (trade.getDirect() == TradeService.SIGNAL_BUY) {
		// // message = "buy,";
		// // } else if (trade.getDirect() == TradeService.SIGNAL_SELL) {
		// // message = "sell,";
		// // } else if (trade.getDirect() == TradeService.SIGNAL_LONGSTOP) {
		// // message = "longstop,";
		// // } else if (trade.getDirect() == TradeService.SIGNAL_LONGSTOP) {
		// // message = "shortstop,";
		// // }
		// // message = message + trade.getCode() + "," + trade.getNumber() +
		// "," + trade.getBuylimit() + "," + trade.getSelllimit();
		// s.send(message.getBytes(), 0);
		// s.recv(0);
		// /
//		readTickFile();
//		// makeMoney2();
//		// makeMoney();
//		// findModel();
//		makeSignal();
////		updateSignal();
//		for (double i = 1; i < 2; i = i + 5) {
//			executeSignal(40, 40);
//		}
		// executeSignal1(70, 65);
	}

	private static void makeSignal() {
		HibernateUtil.updateSignal();
	}

	private static void writeTodayData(String code) throws NumberFormatException, Exception {

		// 创建HttpClient实例
		HttpClient httpclient = new DefaultHttpClient();
		// 创建Get方法实例
		HttpGet httpgets = new HttpGet("http://hq.sinajs.cn/list=" + code);
		HttpResponse response = httpclient.execute(httpgets);
		HttpEntity entity = response.getEntity();
		String str = "";
		if (entity != null) {
			InputStream instreams = entity.getContent();
			str = convertStreamToString(instreams);
			str = str.substring(2, str.length() - 3);
			httpgets.abort();
		}

		String basePath = "d:/data/";
		File file = new File(basePath + code);
		if (!file.exists()) {
			file.mkdir();
		}

		File datafile = new File(basePath + code + "/" + SimpleDateFormat.getDateInstance(1).format(new Date()));

		ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(datafile));
		DayData dd = readRealtimeDatas(code, str);

		oout.writeObject(dd);
		oout.close();

	}

	private static double[] getOrderDayData(String code, int daysO) {
		DayData[] dd = new DayData[daysO];

		int days = daysO;

		if (dataListMap.get(code).size() < days) {
			days = dataListMap.get(code).size();
		}

		Object[] o = Arrays.copyOfRange(dataListMap.get(code).toArray(), dataListMap.get(code).size() - days, dataListMap.get(code).size() - 1);

		double max = 0;
		double min = Integer.MAX_VALUE;

		for (int i = 0; i < o.length; i++) {
			dd[i] = (DayData) o[i];

			if (dd[i].getHigh() > max) {
				max = dd[i].getHigh();
			}
			if (dd[i].getLow() < min) {
				min = dd[i].getLow();
			}
		}

		double r[] = new double[2];
		r[0] = max;
		r[1] = min;

		return r;
	}

	private static DayData readRealtimeDatas(String code, String str) {
		DayData dd = new DayData();
		String[] ddArray = str.split(",");
		SimpleDateFormat myFmt1 = new SimpleDateFormat("yyyy-MM-dd");
		dd.setName(ddArray[0]);
		try {
			dd.setHigh(Double.parseDouble(ddArray[3]));
			dd.setLow(Double.parseDouble(ddArray[4]));
			dd.setOpen(Double.parseDouble(ddArray[2]));
			dd.setClose(Double.parseDouble(ddArray[8]));
			dd.setVol(Integer.parseInt(ddArray[14]));
		} catch (NumberFormatException e) {
		} catch (Exception e) {
		}
		return dd;
	}

	private static void readDatas(String code, String[] datas) throws ParseException {
		for (String s : datas) {
			try {
				DayData dd = new DayData();
				String[] ddArray = s.split(",");
				SimpleDateFormat myFmt1 = new SimpleDateFormat("yyyy-MM-dd");
				dd.setHigh(Double.parseDouble(ddArray[2].substring(1, ddArray[2].length() - 1)));
				dd.setLow(Double.parseDouble(ddArray[3].substring(1, ddArray[3].length() - 1)));
				dd.setOpen(Double.parseDouble(ddArray[1].substring(1, ddArray[1].length() - 1)));
				dd.setClose(Double.parseDouble(ddArray[4].substring(1, ddArray[4].length() - 1)));
				dd.setVol(Integer.parseInt(ddArray[5].substring(1, ddArray[5].length() - 1)));
				dd.setDataDate(myFmt1.parse(ddArray[0].substring(1, ddArray[0].length() - 1)));
				dd.setName(Dictionary.SinaDataDictionary.get(code));
				dd.setSinaCode(code);

				Session session = HibernateUtil.getSessionFactory().openSession();
				session.beginTransaction();
				session.save(dd);

				session.getTransaction().commit();

				// if (dataListMap.get(code) == null) {
				// dataListMap.put(code, new ArrayList<DayData>());
				// }
				// dataListMap.get(code).add(dd);
			} catch (Exception e) {
				// e.printStackTrace();
			}
		}

	}

	private static double getATR(String code, int days0) {
		int days = days0;

		if (dataListMap.get(code).size() < days) {
			days = dataListMap.get(code).size();
		}

		List<DayData> dataList = dataListMap.get(code);
		double cout = 0;
		for (int i = 1; i < days + 1; i++) {
			double atr1 = Math.abs(dataList.get(dataList.size() - i).getHigh() - dataList.get(dataList.size() - i).getLow());
			double atr2 = Math.abs(dataList.get(dataList.size() - i - 1).getClose() - dataList.get(dataList.size() - i).getLow());
			double atr3 = Math.abs(dataList.get(dataList.size() - i - 1).getClose() - dataList.get(dataList.size() - i).getHigh());
			double atr = Math.max(atr1, atr2);
			atr = Math.max(atr, atr3);
			cout = cout + atr;
		}

		return cout / days;
	}

	private static Map<String, List<DayData>> dataListMap = new HashMap<String, List<DayData>>();

	public static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	public static void readTickFile() throws IOException, ParseException {

		File[] files = FileUtil.readFile("D:/xd");
		for (int i = 0; i < files.length; i++) {
			System.out.print(files[i].getName());
			Session session = HibernateUtil.getSessionFactory().openSession();
			BufferedReader reader = null;
			try {

				double dayHigh = 0;
				double dayLow = 99999999;
				double dayOpen = 0;
				double dayClose = 0;
				double todayVol = 0;
				Date dayDate = null;
				reader = new BufferedReader(new FileReader(files[i]));
				String tempString = null;
				int icount = 0;
				session.beginTransaction();

				Double tVol = null;
				Long tTurnOver = null;
				double tBuyPrice = 0;
				double tSellPrice = 0;
				double tAverPrice = 0;

				double[] speed10 = new double[10];
				double[] speed30 = new double[30];
				double[] speed60 = new double[60];
				double[] speed180 = new double[180];

				int count10 = 0;
				int count30 = 0;
				int count60 = 0;
				int count180 = 0;

				double lastAveragePrice = 0;
				double lastBuyPrice = 0;
				double lastSellPrice = 0;

				double deltaStep = 300;
				while ((tempString = reader.readLine()) != null) {
					SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss SSS");
					String[] splitString = tempString.split(",");

					Date d = df.parse(splitString[1] + " " + splitString[2] + " " + splitString[3]);
					TickData td = new TickData();
					td.setCode(splitString[0]);
					td.setTickDate(d);
					if (td.getTickDate().getHours() == 0 || td.getTickDate().getHours() == 1 || td.getTickDate().getHours() == 2 || td.getTickDate().getHours() == 3 || td.getTickDate().getHours() == 4 || td.getTickDate().getHours() == 5) {
						Calendar c = Calendar.getInstance();
						c.setTime(td.getTickDate());
						c.add(Calendar.DATE, 1);
						td.setTickDate(c.getTime());
					}

					td.setTicks(d.getTime());

					td.setSellPrice(Double.parseDouble(splitString[4]));
					td.setSellVol(Double.parseDouble(splitString[5]));
					td.setBuyPrice(Double.parseDouble(splitString[6]));
					td.setBuyVol(Double.parseDouble(splitString[7]));
					td.setTodayVol(Double.parseDouble(splitString[9]));
					td.setTodayPosition(Double.parseDouble(splitString[10]));
					td.setTodayTurnOver(Long.parseLong(splitString[8]));
					td.setBuySellAbs(Math.abs(td.getSellPrice() - td.getBuyPrice()));
					if (tVol != null) {
						td.setDeltaTurnOver(td.getTodayTurnOver() - tTurnOver);
						td.setDeltaVol(td.getTodayVol() - tVol);

						if (td.getDeltaVol() != 0) {
							td.setAveragePrice(td.getDeltaTurnOver() / td.getDeltaVol() / Dictionary.ATRTimesDictionary.get(td.getCode().replaceAll("[0-9]*$", "")));
						}

					}

					// if (td.getSellPrice() - tSellPrice >= 0 &&
					// td.getBuyPrice() - tBuyPrice >= 0) {
					// td.setSignal(0);
					// } else if (td.getSellPrice() - tSellPrice <= 0 &&
					// td.getBuyPrice() - tBuyPrice <= 0) {
					// td.setSignal(1);
					// }

					if (td.getAveragePrice() == tBuyPrice) {
						td.setSellNumber(td.getDeltaVol());
					} else if (td.getAveragePrice() == tSellPrice) {
						td.setBuyNumber(td.getDeltaVol());
					} else if (Math.abs(td.getAveragePrice() - tBuyPrice) > Math.abs(td.getAveragePrice() - tSellPrice)) {
						if (td.getAveragePrice() > tSellPrice) {
							td.setBuyNumber(td.getDeltaVol());
						} else {

							double t1 = (td.getDeltaTurnOver() - Math.floor(td.getAveragePrice() * 0.1) * 10 * td.getDeltaVol() * 5) * 0.2 * 0.1;
							double t2 = td.getDeltaVol() - t1;
							int scount = 0;
							while (t2 < 0) {
								scount = scount + 10;
								t1 = (td.getDeltaTurnOver() - (Math.floor(td.getAveragePrice() * 0.1) * 10 + scount) * td.getDeltaVol() * 5) * 0.2 * 0.1;
								t2 = td.getDeltaVol() - t1;
							}

							if (t1 > t2) {
								td.setBuyNumber(t1);
								td.setSellNumber(t2);
							} else {
								td.setBuyNumber(t2);
								td.setSellNumber(t1);
							}

						}

					} else if (Math.abs(td.getAveragePrice() - tBuyPrice) < Math.abs(td.getAveragePrice() - tSellPrice)) {
						if (td.getAveragePrice() < tBuyPrice) {
							td.setSellNumber(td.getDeltaVol());
						} else {
							double t1 = (td.getDeltaTurnOver() - Math.floor(td.getAveragePrice() * 0.1) * 10 * td.getDeltaVol() * 5) * 0.2 * 0.1;
							double t2 = td.getDeltaVol() - t1;
							int scount = 0;
							while (t2 < 0) {
								scount = scount + 10;
								t1 = (td.getDeltaTurnOver() - (Math.floor(td.getAveragePrice() * 0.1) * 10 + scount) * td.getDeltaVol() * 5) * 0.2 * 0.1;
								t2 = td.getDeltaVol() - t1;
							}

							if (t1 > t2) {
								td.setBuyNumber(t2);
								td.setSellNumber(t1);
							} else {
								td.setBuyNumber(t1);
								td.setSellNumber(t2);
							}

						}
					} else {
						td.setBuyNumber(td.getDeltaVol() / 2);
						td.setBuyNumber(td.getDeltaVol() / 2);
					}

					// if (Math.abs(tSellPrice - td.getSellPrice())
					// >Math.abs(tBuyPrice-td.getBuyPrice()) &&
					// td.getDeltaTurnOver()>=500*10000) {
					// td.setSignal(0);
					// } else if (Math.abs(tSellPrice - td.getSellPrice())
					// <Math.abs(tBuyPrice-td.getBuyPrice()) &&
					// td.getDeltaTurnOver()>=500*10000) {
					// td.setSignal(1);
					// }

					tVol = td.getTodayVol();
					tTurnOver = td.getTodayTurnOver();
					tBuyPrice = td.getBuyPrice();
					tSellPrice = td.getSellPrice();
					tAverPrice = td.getAveragePrice();
					if (td.getSellPrice() < dayLow) {
						dayLow = td.getSellPrice();
					}
					if (td.getBuyPrice() > dayHigh) {
						dayHigh = td.getBuyPrice();
					}
					dayClose = (td.getBuyPrice() + td.getSellPrice()) / 2;
					if (icount == 0) {
						dayOpen = (td.getBuyPrice() + td.getSellPrice()) / 2;
						icount++;
					}
					dayDate = td.getTickDate();
					todayVol = td.getTodayVol();

					if (td.getDeltaVol() > deltaStep) {
						deltaStep = 300;
						td.setStatus(1);
					} else {
						deltaStep = deltaStep - td.getDeltaVol();
						td.setStatus(0);
					}
					speed10[count10] = td.getBuyNumber() - td.getSellNumber();
					speed30[count30] = td.getBuyNumber() - td.getSellNumber();
					speed60[count60] = td.getBuyNumber() - td.getSellNumber();
					speed180[count180] = td.getBuyNumber() - td.getSellNumber();

					count10++;
					if (count10 >= 10) {
						count10 = 0;
					}

					count30++;
					if (count30 >= 30) {
						count30 = 0;
					}
					count60++;
					if (count60 >= 60) {
						count60 = 0;
					}
					count180++;
					if (count180 >= 180) {
						count180 = 0;
					}

					td.setSpeed10(averageCount(speed10));
					td.setSpeed20(averageCount(speed30));
					td.setSpeed60(averageCount(speed60));
					td.setSpeed180(averageCount(speed180));

					if (td.getSellNumber() > 300) {
						td.setSignal(0);
					}

					if (td.getBuyNumber() > 300) {
						td.setSignal(1);
					}

					td.setDeltaBuyPrice(Math.abs(td.getBuyPrice() - lastSellPrice));
					td.setDeltaSellPrice(Math.abs(td.getSellPrice() - lastBuyPrice));

					if (td.getAveragePrice() > 0) {
						td.setDeltaAveragePrice(Math.abs(td.getAveragePrice() - lastAveragePrice));
						lastAveragePrice = td.getAveragePrice();
					}

					lastBuyPrice = td.getBuyPrice();
					lastSellPrice = td.getSellPrice();

					session.save(td);

				}
				session.getTransaction().commit();
				session.close();
				reader.close();
				// importDayData(dayHigh, dayLow, dayOpen, dayClose, todayVol,
				// dayDate, files[i].getName());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private static double averageCount(double[] darray) {
		double sum = 0;
		for (int i = 0; i < darray.length; i++) {
			sum = sum + darray[i];
		}
		return sum / darray.length;
	}

	// 买盘速度加速
	public static void makeMoney11() {
		// List<TickData> tlist = HibernateUtil.selectAllData(code, volMax);
		// for (TickData td : tlist) {
		// List<TickData> tlist1 =
		// HibernateUtil.selectTickDataByBigThanId(td.getId(), code);
	}

	public static void makeMoney() {
		// String ss[] = { "a1701", "ag1701", "al1701", "au1701", "bu1701",
		// "c1701", "cs1701", "cu1701", "i1701", "j1701", "jd1701", "jm1701",
		// "l1701", "m1701",
		// "ni1701", "p1701", "pb1701", "pp1701", "rb1701", "ru1701", "sn1701",
		// "v1701", "y1701", "zn1701", "CF701" , "WH701", "SR701", "TA701",
		// "FG701", "OI701", "MA701", "RM701", "ZC701"};

		// String ss[] = { "a1701", "ag1701", "al1701", "au1701", "bu1701",
		// "c1701", "cs1701", "cu1701", "i1701", "j1701", "jd1701", "jm1701",
		// "l1701", "m1701",
		// "ni1701", "p1701", "pb1701", "pp1701", "rb1701", "ru1701", "sn1701",
		// "v1701", "y1701", "zn1701"};

		String ss[] = { "al1702" };

		double volMax = 600;
		double volTrigge = 100;
		double priceStep = 5;

		for (String code : ss) {

			List<TickData> tlist = HibernateUtil.selectAllData(code, volMax);
			for (TickData td : tlist) {
				List<TickData> tlist1 = HibernateUtil.selectTickDataByBigThanId(td.getId(), code);
				boolean broken = false;
				boolean buysignal = false;
				boolean sellsignal = false;
				double lastVol = 0;
				int beginId = 0;
				if (td.getSellVol() > volMax) {
					lastVol = td.getSellVol();
				}
				if (td.getBuyVol() > volMax) {
					lastVol = td.getBuyVol();
				}
				int scount = 0;
				for (int i = 0; i < tlist1.size(); i++) {
					if (td.getSellVol() > volMax) {
						if (tlist1.get(i).getSellPrice() == td.getSellPrice()) {
							if (tlist1.get(i).getSellVol() < lastVol) {
								scount++;
								lastVol = tlist1.get(i).getSellVol();
								if (tlist1.get(i).getSellVol() < volTrigge && scount >= 5) {
									beginId = tlist1.get(i).getId();
									buysignal = true;
									break;
								}
							} else {
								broken = true;
								break;
							}
						}
					}
					if (td.getBuyVol() > volMax) {
						if (tlist1.get(i).getBuyPrice() == td.getBuyPrice()) {
							if (tlist1.get(i).getBuyVol() < lastVol) {
								scount++;
								lastVol = tlist1.get(i).getBuyVol();
								if (tlist1.get(i).getBuyVol() < volTrigge && scount >= 5) {
									beginId = tlist1.get(i).getId();
									sellsignal = true;
									break;
								}
							} else {
								broken = true;
								break;
							}
						}

					}
				}

				if (buysignal) {

					List<TickData> tlist2 = HibernateUtil.selectTickDataByBigThanId(beginId, code);
					if (td.getSellVol() > volMax) {

						double high = td.getSellPrice();
						boolean beginWin = false;
						for (int i = 0; i < tlist2.size(); i++) {

							if (tlist2.get(i).getSellPrice() <= td.getSellPrice() - priceStep) {
								System.out.println("beginId" + beginId + " stop loss " + tlist2.get(i + 1).getId() + " " + (tlist2.get(i + 1).getBuyPrice() - td.getSellPrice()));
								break;
							} else if (tlist2.get(i).getSellPrice() > high) {
								beginWin = true;
								high = tlist2.get(i).getSellPrice();
							} else if (beginWin && tlist2.get(i).getSellPrice() < high) {
								System.out.println("beginId" + beginId + " stop win " + tlist2.get(i + 1).getId() + " " + (tlist2.get(i + 1).getBuyPrice() - td.getSellPrice()));
								break;
							}

						}

					}

				}

				if (sellsignal) {

					List<TickData> tlist2 = HibernateUtil.selectTickDataByBigThanId(beginId, code);
					if (td.getBuyVol() > volMax) {
						double low = td.getBuyPrice();
						boolean beginWin = false;

						for (int i = 0; i < tlist2.size(); i++) {
							if (tlist2.get(i).getBuyPrice() >= td.getBuyPrice() + priceStep) {
								System.out.println("beginId" + beginId + " stop loss " + tlist2.get(i + 1).getId() + " " + (td.getBuyPrice() - tlist2.get(i + 1).getSellPrice()));
								break;
							} else if (tlist2.get(i).getBuyPrice() < low) {
								beginWin = true;
								low = tlist2.get(i).getBuyPrice();
							} else if (beginWin && tlist2.get(i).getSellPrice() > low) {
								System.out.println("beginId" + beginId + " stop win " + tlist2.get(i + 1).getId() + " " + (td.getBuyPrice() - tlist2.get(i + 1).getSellPrice()));
								break;
							}

						}
					}
				}

			}
		}

	}

	private static double getClosesC(double d) {

		return Math.ceil(d * 0.1) * 10;
	}

	private static double getClosesF(double d) {

		return Math.floor(d * 0.1) * 10;
	}

	// 跳空限价抢筹
	public static void makeMoney2() {

		String ss[] = { "cu1702" };
		for (String code : ss) {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");

			List<TickData> tlist = HibernateUtil.selectRandomData(code, 1000 * 10000);
			long buyTime = 0;
			long sellTime = 0;
			int count = 0;
			double win = 0;
			for (TickData td : tlist) {

				boolean buyF = false;
				boolean sellF = false;

				List<TickData> lmax = HibernateUtil.selectSignalMax(td.getCode(), String.valueOf(td.getId()));
				List<TickData> lmin = HibernateUtil.selectSignalMin(td.getCode(), String.valueOf(td.getId()));
				if (lmax.size() > 49 && td.getAveragePrice() == lmax.get(0).getAveragePrice()) {
					buyF = true;
					td.setSignal(0);
					Session s = HibernateUtil.getSessionFactory().openSession();
					s.beginTransaction();
					s.update(td);
					s.getTransaction().commit();
					break;

				}
				if (lmin.size() > 49 && td.getAveragePrice() == lmin.get(0).getAveragePrice()) {
					sellF = true;
					td.setSignal(1);
					Session s = HibernateUtil.getSessionFactory().openSession();
					s.beginTransaction();
					s.update(td);
					s.getTransaction().commit();
					break;
				}

				// if (buyF) {
				// int id = td.getId();
				// id = id + 5;
				// TickData tdata =
				// HibernateUtil.getTickDataById(String.valueOf(id), code);
				// List<TickData> llow =
				// HibernateUtil.selectSignalLow(td.getCode(),
				// String.valueOf(id));
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// continue;
				// }
				// boolean c = false;
				// while (tdata.getAveragePrice() >
				// llow.get(0).getAveragePrice()) {
				// id++;
				// tdata = HibernateUtil.getTickDataById(String.valueOf(id),
				// code);
				// llow = HibernateUtil.selectSignalLow(td.getCode(),
				// String.valueOf(id));
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// break;
				// }
				// }
				// if (c) {
				// continue;
				// }
				//
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// continue;
				// }
				// if (Math.abs((tdata.getSellPrice() - td.getBuyPrice())) <
				// 500) {
				// if (td.getTicks() - buyTime > 1000 * 60 * 10) {
				// buyTime = td.getTicks();
				// win = win + tdata.getBuyPrice() - td.getSellPrice();
				// count++;
				// System.out.println(td.getId() + " " +
				// df.format(td.getTickDate()) + " " + (tdata.getBuyPrice() -
				// td.getSellPrice()) + " " + df.format(tdata.getTickDate()) +
				// " " + tdata.getId());
				//
				// }
				// }
				// } else if (sellF) {
				// int id = td.getId();
				// id = id + 5;
				// TickData tdata =
				// HibernateUtil.getTickDataById(String.valueOf(id), code);
				// List<TickData> llow =
				// HibernateUtil.selectSignalHigh(td.getCode(),
				// String.valueOf(id));
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// continue;
				// }
				// boolean c = false;
				// while (tdata.getAveragePrice() <
				// llow.get(0).getAveragePrice()) {
				// id++;
				// tdata = HibernateUtil.getTickDataById(String.valueOf(id),
				// code);
				// llow = HibernateUtil.selectSignalHigh(td.getCode(),
				// String.valueOf(id));
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// break;
				// }
				// }
				// if (c) {
				// continue;
				// }
				//
				// if (tdata == null || llow == null || llow.size() == 0 ||
				// llow.get(0) == null) {
				// continue;
				// }
				// if (Math.abs((tdata.getSellPrice() - td.getBuyPrice())) <
				// 500) {
				// if (td.getTicks() - sellTime > 1000 * 60 * 10) {
				// sellTime = td.getTicks();
				// win = win + td.getBuyPrice() - tdata.getSellPrice();
				// count++;
				// System.out.println(td.getId() + " " +
				// df.format(td.getTickDate()) + " " + (td.getBuyPrice() -
				// tdata.getSellPrice()) + " " + df.format(tdata.getTickDate())
				// + " " + tdata.getId());
				// }
				// }
				// }
			}
			if (count > 0) {
				System.out.println(code + " " + win + " " + count);
			}

		}

	}

	public static void findModel() {
		List<TickData> tlist = HibernateUtil.selectAllData("bu1706");
		int continueC = 0;
		int continueS = 0;
		int maxC = 0;
		int maxS = 0;
		for (int i = 0; i < tlist.size() - 1; i++) {
			if (tlist.get(i + 1).getAveragePrice() >= tlist.get(i).getAveragePrice()) {
				if (tlist.get(i + 1).getAveragePrice() > tlist.get(i).getAveragePrice()) {
					continueC++;
				}
				if (continueC > maxC) {
					maxC = continueC;
				}
			} else {
				continueC = 0;
			}

			if (tlist.get(i + 1).getAveragePrice() <= tlist.get(i).getAveragePrice()) {
				if (tlist.get(i + 1).getAveragePrice() < tlist.get(i).getAveragePrice()) {
					continueS++;
				}
				if (continueS > maxC) {
					maxS = continueS;
				}
			} else {
				continueS = 0;
			}

		}
		System.out.println(maxC);
		System.out.println(maxS);
	}

	public static void makeMoney1() {
		// String ss[] = { "a1701", "ag1701", "al1701", "au1701", "bu1701",
		// "c1701", "cs1701", "cu1701", "i1701", "j1701", "jd1701", "jm1701",
		// "l1701", "m1701",
		// "ni1701", "p1701", "pb1701", "pp1701", "rb1701", "ru1701", "sn1701",
		// "v1701", "y1701", "zn1701", "CF701" , "WH701", "SR701", "TA701",
		// "FG701", "OI701", "MA701", "RM701", "ZC701"};

		// String ss[] = { "a1701", "ag1701", "al1701", "au1701", "bu1701",
		// "c1701", "cs1701", "cu1701", "i1701", "j1701", "jd1701", "jm1701",
		// "l1701", "m1701",
		// "ni1701", "p1701", "pb1701", "pp1701", "rb1701", "ru1701", "sn1701",
		// "v1701", "y1701", "zn1701"};

		String ss[] = { "cu1701" };

		List<TickData> tToplist = HibernateUtil.selectTopAbs("");

		Map<String, Double> m = new HashMap<String, Double>();
		Map<String, Double> ml = new HashMap<String, Double>();
		for (TickData td : tToplist) {
			m.put(td.getCode(), td.getBuySellAbs());

		}

		List<TickData> tAvglist = HibernateUtil.selectAvgTurnOver("");
		Map<String, Double> mv = new HashMap<String, Double>();
		for (TickData td : tAvglist) {
			mv.put(td.getCode(), td.getBuySellAbs());

		}
		for (String code : ss) {

			// TickData t = HibernateUtil.selectTopData(code);

			List<TickData> tlist = HibernateUtil.selectSignalData(code, 30);

			// List<TickData> tlist = HibernateUtil.selectRandomData(code);

			for (int i = 21; i < 22; i++) {
				int count = 0;
				double win = 0;
				for (TickData td : tlist) {
					SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
					// Calendar c = Calendar.getInstance();
					// c.setTime(td.getTickDate());
					// c.add(Calendar.SECOND, 10);

					// TickData tdata =
					// HibernateUtil.getTickData(c.getTime().getTime(),
					// code);
					TickData tdata = HibernateUtil.getTickDataById(String.valueOf(td.getId() + i), code);
					TickData tdata1 = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1), code);
					//
					// TickData tdata2 =
					// HibernateUtil.getTickDataById(String.valueOf(td.getId()+1),
					// code);
					//
					// TickData tdata3 =
					// HibernateUtil.getTickDataById(String.valueOf(td.getId()+1),
					// code);
					//
					// TickData tdata4 =
					// HibernateUtil.getTickDataById(String.valueOf(td.getId()+1224),
					// code);

					if (tdata != null) {
						if (td.getSignal() == 0) {
							win = win + (tdata1.getBuyPrice() - tdata.getSellPrice());
							count++;
							System.out.println(tdata1.getId() + " " + df.format(tdata1.getTickDate()) + "   " + (tdata1.getBuyPrice() - tdata.getSellPrice()) + " " + df.format(tdata.getTickDate()) + " " + tdata.getId());

						} else if (td.getSignal() == 1) {
							win = win + (tdata.getBuyPrice() - tdata1.getSellPrice());
							count++;
							System.out.println(tdata1.getId() + " " + df.format(tdata1.getTickDate()) + "   " + (tdata.getBuyPrice() - tdata1.getSellPrice()) + " " + df.format(tdata.getTickDate()) + " " + tdata.getId());

						}
					}
				}
				if (count > 0) {
					System.out.println(code + " " + i + " " + win + " " + count);
				}

			}
		}

	}

	public static void importDayData(double dayHigh, double dayLow, double dayOpen, double dayClose, double todayVol, Date date, String code) {
		DayData dd = new DayData();
		dd.setHigh(dayHigh);
		dd.setLow(dayLow);
		dd.setOpen(dayOpen);
		dd.setClose(dayClose);
		dd.setVol((int) todayVol);
		dd.setDataDate(date);
		dd.setName(code);

		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
		session.save(dd);
		session.getTransaction().commit();
	}

	private static void readRealData(String data) throws ParseException {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss SSS");
		String[] splitString = data.split(",");
		Date d = df.parse(splitString[0] + " " + splitString[1] + " " + splitString[2]);
		TickData td = new TickData();
		td.setCode("");
		td.setTickDate(d);
		td.setTicks(d.getTime());
		td.setSellPrice(Double.parseDouble(splitString[3]));
		td.setSellVol(Double.parseDouble(splitString[4]));
		td.setBuyPrice(Double.parseDouble(splitString[5]));
		td.setBuyVol(Double.parseDouble(splitString[6]));
		td.setTodayVol(Double.parseDouble(splitString[8]));
		td.setTodayPosition(Double.parseDouble(splitString[9]));
		// if (insertCount % 100 == 0) {
		// session.beginTransaction();
		// }
		//
		// session.save(td);
		// if (insertCount % 100 == 0) {
		// session.getTransaction().commit();
		// }
		insertCount++;
	}

	private static boolean tradeTime(Date d) {
		boolean tradeTime = false;
		int hours = d.getHours();

		int minutes = d.getMinutes();
		int seconds = d.getSeconds();

		double now = (1 / 10e1) * hours + (1 / 10e3) * minutes + (1 / 10e5) * seconds; // 时间格式0.145100

		if (now > 0.090459 && now < 0.1015) {
			tradeTime = true;
		} else if (now > 0.103059 && now < 0.120000) {
			tradeTime = true;
		} else if (now > 0.133459 && now < 0.145459) {
			tradeTime = true;
		} else if (now > 0.210459) {
			tradeTime = true;
		} else {
			tradeTime = false;
		}

		return tradeTime;
	}

	private static void executeSignal(double stopLossMoney, double stopWinMoney) throws ParseException {

		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss SSS");
		String code = "zn1702";
		int tSignal = 0;
		String beginDate = "20161211 20:59:59 000";
		String endDate = "20161212 15:00:01 000";
		List<TickData> signalDataList = HibernateUtil.searchSignal(code, tSignal, df.parse(beginDate).getTime(), df.parse(endDate).getTime());

		long signalPeriod = 60 * 1000 * 1;
		long lastSignalTick = 0;
		boolean continueSignal = false;

		double count = 0;
		double icount = 0;
		for (TickData td : signalDataList) {
			if (continueSignal && td.getTicks() < lastSignalTick + signalPeriod) {
				continue;
			}

			if (!tradeTime(td.getTickDate())) {
				continue;
			}

			lastSignalTick = td.getTicks();

			TickData buyTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1), code);
			if (buyTick == null) {
				continue;
			}
			double maxPrice = buyTick.getSellPrice();

			int holdPosition = 0;
			while (true) {
				holdPosition++;
				TickData holdTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition), code);

				if (holdTick == null) {
					break;
				}

				if (holdTick.getSellPrice() > maxPrice) {
					maxPrice = holdTick.getSellPrice();
				} else if (holdTick.getSellPrice() < maxPrice - stopLossMoney) {
					break;
				} else if (holdTick.getSellPrice() - buyTick.getSellPrice() > stopWinMoney) {
					break;
				}

			}
			TickData sellTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition + 1), code);

			int ip = 0;
			while (sellTick == null) {
				ip++;
				sellTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition + 1 - ip), code);
			}

			// if (sellTick.getBuyPrice() - buyTick.getSellPrice() > 20) {
			// Session s = HibernateUtil.getSessionFactory().openSession();
			// s.beginTransaction();
			// td.setSignal(20000);
			// s.update(td);
			// s.getTransaction().commit();
			// s.close();

			icount++;
			count = count + (sellTick.getBuyPrice() - buyTick.getSellPrice());
			System.out.println(buyTick.getId() + " " + df.format(buyTick.getTickDate()) + " " + buyTick.getSellPrice() + " " + (sellTick.getBuyPrice() - buyTick.getSellPrice()) + " " + sellTick.getId() + " " + df.format(sellTick.getTickDate()) + " " + sellTick.getBuyPrice());
			// }
		}
		lastSignalTick = 0;
		signalDataList = HibernateUtil.searchSignal(code, 1, df.parse(beginDate).getTime(), df.parse(endDate).getTime());
		for (TickData td : signalDataList) {
			if (continueSignal && td.getTicks() < lastSignalTick + signalPeriod) {
				continue;
			}
			if (!tradeTime(td.getTickDate())) {
				continue;
			}

			lastSignalTick = td.getTicks();

			TickData sellTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1), code);

			double maxPrice = sellTick.getBuyPrice();

			int holdPosition = 0;
			while (true) {
				holdPosition++;
				TickData holdTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition), code);

				if (holdTick == null) {
					continue;
				}

				if (holdTick.getBuyPrice() < maxPrice) {
					maxPrice = holdTick.getBuyPrice();
				} else if (holdTick.getBuyPrice() > maxPrice + stopLossMoney) {
					break;
				} else if (sellTick.getBuyPrice() - holdTick.getSellPrice() > stopWinMoney) {
					break;
				}

			}
			TickData buyTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition + 1), code);
			int ip = 0;
			while (buyTick == null) {
				ip++;
				buyTick = HibernateUtil.getTickDataById(String.valueOf(td.getId() + 1 + holdPosition - ip), code);
			}

			System.out.println("sss" + " " + buyTick.getId() + " " + df.format(buyTick.getTickDate()) + " "
					+ buyTick.getSellPrice() + " " + (sellTick.getBuyPrice() - buyTick.getSellPrice()) + " "
					+ sellTick.getId() + " " + df.format(sellTick.getTickDate()) + " " + sellTick.getBuyPrice());
			count = count + (sellTick.getBuyPrice() - buyTick.getSellPrice());

		}
		System.out.println(icount + " " + count);
	}

	private static void updateSignal() throws ParseException {
		List<TickData> signalDataList = HibernateUtil.selectAllData("zn1702");
		double minBuyPrice = 9999999;
		double maxSellPrice = 0;
		// for (TickData td : signalDataList) {
		// if(td.getSellPrice()>maxSellPrice){
		// maxSellPrice=td.getSellPrice();
		// }
		// if(maxSellPrice-td.getSellPrice()>40){
		// System.out.println(td.getId());
		// maxSellPrice=0;
		// }
		// }

		for (TickData td : signalDataList) {
			if (td.getBuyPrice() < minBuyPrice) {
				minBuyPrice = td.getBuyPrice();
			}
			if (td.getBuyPrice() - minBuyPrice > 40) {
				Session s = HibernateUtil.getSessionFactory().openSession();
				s.beginTransaction();
				td.setSignal(0);
				s.save(td);
				s.getTransaction().commit();
				minBuyPrice = 9999999;
			}
		}

	}
}
